#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i(a);i<=(b);++i)
#define req(i,a,b) for(int i(a);i>=(b);--i)
using namespace std;
	vector<vector<int>> prex[2],nxtx[2],prey[2],nxty[2];
	vector<vector<int>> pret[2],nxtt[2];
signed main()
{
	freopen("star.in","r",stdin);
	freopen("star.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	int n,m; cin>>n>>m;
	vector<string> a(n),b(m);
	rep(i,0,n-1) cin>>a[i];
	rep(j,0,m-1)
	{
		b[j].resize(n);
		rep(i,0,n-1) b[j][i]=a[i][j];
	}
	prex[0].resize(max(n,m)),
	prex[1].resize(max(n,m)),
	prey[0].resize(max(n,m)),
	prey[1].resize(max(n,m)),
	nxtx[0].resize(max(n,m)),
	nxtx[1].resize(max(n,m)),
	nxty[0].resize(max(n,m)),
	nxty[1].resize(max(n,m));
	pret[0].resize(max(n,m)),
	pret[1].resize(max(n,m)),
	nxtt[0].resize(max(n,m)),
	nxtt[1].resize(max(n,m));
	rep(i,0,max(n,m)-1)
	{
	prex[0][i].resize(max(n,m)),
	prex[1][i].resize(max(n,m)),
	prey[0][i].resize(max(n,m)),
	prey[1][i].resize(max(n,m)),
	nxtx[0][i].resize(max(n,m)),
	nxtx[1][i].resize(max(n,m)),
	nxty[0][i].resize(max(n,m)),
	nxty[1][i].resize(max(n,m));
	pret[0][i].resize(max(n,m)),
	pret[1][i].resize(max(n,m)),
	nxtt[0][i].resize(max(n,m)),
	nxtt[1][i].resize(max(n,m));
	}
	rep(rev,0,1)
	{
		rep(i,0,n-1) rep(j,0,m-1)
		{
			prex[rev][i][j]=(i&&a[i][j]==a[i-1][j])?(prex[rev][i-1][j]+(a[i][j]==a[i-1][j])):0;
			prey[rev][i][j]=(j&&a[i][j]==a[i][j-1])?(prey[rev][i][j-1]+(a[i][j]==a[i][j-1])):0;
		}
		req(i,n-1,0) req(j,m-1,0)
		{
			nxtx[rev][i][j]=(i<n-1&&a[i][j]==a[i+1][j])?(nxtx[rev][i+1][j]+(a[i][j]==a[i+1][j])):0;
			nxty[rev][i][j]=(j<m-1&&a[i][j]==a[i][j+1])?(nxty[rev][i][j+1]+(a[i][j]==a[i][j+1])):0;
		}
		swap(n,m); swap(a,b);
	}
	int ans=0;
	function<void(int,int,int,int,int)> solve=[&](int stx,int edx,int sty,int edy,int rev)->void
	{
		if(edx-stx<2||edy-sty<2) return;
		if(edx-stx>edy-sty) swap(stx,sty),swap(edx,edy),rev^=1;
		int mid=(sty+edy)>>1,lim=edx-stx-1;
		rep(i,stx,edx-1)
		{
			rep(len,0,edx-stx-1) nxtt[0][i-stx][len]=pret[0][i-stx][len]=nxtt[1][i-stx][len]=pret[1][i-stx][len]=0;
			rep(j,max(mid-prey[rev][i][mid],sty),mid) ++nxtt[0][i-stx][min(nxtx[rev][i][j],lim)],++pret[0][i-stx][min(prex[rev][i][j],lim)];
			rep(j,mid,min(edy,mid+nxty[rev][i][mid]+1)-1) ++nxtt[1][i-stx][min(nxtx[rev][i][j],lim)],++pret[1][i-stx][min(prex[rev][i][j],lim)];
			req(l,lim-1,0) nxtt[0][i-stx][l]+=nxtt[0][i-stx][l+1],nxtt[1][i-stx][l]+=nxtt[1][i-stx][l+1],pret[0][i-stx][l]+=pret[0][i-stx][l+1],pret[1][i-stx][l]+=pret[1][i-stx][l+1];
		}
		rep(i,stx,edx-1)
		{
			rep(k,i+1,edx-1)
			{
				if(!rev&&a[i][mid]!=a[k][mid]) continue;
				if(rev&&b[i][mid]!=b[k][mid]) continue;
				int resl=0,resr=0;
				if(prey[rev][i][mid]<prey[rev][k][mid]) resl+=nxtt[0][i-stx][k-i];
				else resl+=pret[0][k-stx][k-i];
				if(nxty[rev][i][mid]<nxty[rev][k][mid]) resr+=nxtt[1][i-stx][k-i];
				else resr+=pret[1][k-stx][k-i];
				ans+=resl*resr-(nxtx[rev][i][mid]>=k-i);
			}
		}
		solve(stx,edx,sty,mid,rev),solve(stx,edx,mid+1,edy,rev);
	};
	solve(0,n,0,m,0);cout<<(ans);
	return 0;
}
